/////////////////////////////////////////////////////////////////////////////
// Name:        ax_activator.h
// Purpose:     Standard activator classes
// Author:      Julian Smart
// Modified by:
// Created:     2009-03-20
// RCS-ID:
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#ifndef _AX_ACTIVATOR_H_
#define _AX_ACTIVATOR_H_

/**
    @class AxActivator

    This class defines how a menu item responds to user input such as
    activation. Derive from this class, override functions such as Activate,
    and associate an instance with a menu item.

    The virtual function BeforeDisplay is called just before it is displayed,
    and UpdateUI is called periodically to allow on-idle updating.
    
    Activate is called when the item has been activated (for example
    on return or double-click), and Select is called when the item has
    been selected (highlighted).

    If Activate returns an AxMenu pointer, the menu immediately becomes
    managed by the menu controller (so don't delete it) and the menu is
    shown. Return NULL if you don't need a new menu to be shown.

    If the AxMenuItem has been marked as dynamic, you can return a new AxMenu
    each time. If it's static, return the menu item's submenu if it exists,
    else create a new menu item.

    @category{ax}
*/

/*
 * Styles and types
 */

/*
 * Forward declarations
 */

class AxMenuItem;
class AxMenu;
class AxMenuItemData;
class AxResource;
class AxMenuController;

/**
    @class AxActivator

    AxActivator objects are used when an item is activated.

    @category{ax}

 */

class AxActivator: public wxEvtHandler
{
    DECLARE_CLASS( AxActivator )

public:
// Constructors

    AxActivator(AxMenuItem* item = NULL) { Init(); m_menuItem = item; }
    ~AxActivator() {}

// Operations

    void Init() { m_menuItem = NULL; }
    void Copy(const AxActivator& activator) { m_menuItem = activator.m_menuItem; }

    virtual AxActivator* Clone() const = 0;

    /// Called when the user activates a menu item by pressing return or double-clicking
    virtual AxMenu* Activate(AxMenuController* controller, AxMenuItem* item) = 0;

    /// Called when a menu is reactivated, for example by going up. This
    /// allows a view to be shown again, without generating all the menus.
    virtual bool Reactivate(AxMenuController* WXUNUSED(controller), AxMenuItem* WXUNUSED(item)) { return false; }

    /// Called when the user selects an item, for example to describe the item
    virtual bool Select(AxMenuController* controller, AxMenuItem* item);

    /// Called just before the menu item is displayed.
    virtual bool BeforeDisplay(AxMenuController* controller, AxMenuItem* item);

    /// Called during display, at intervals.
    virtual bool UpdateUI(AxMenuController* controller, AxMenuItem* item);

    /// Returns the corresponding menu item.
    AxMenuItem* GetMenuItem() const { return m_menuItem; }
    void SetMenuItem(AxMenuItem* item) { m_menuItem = item; }

protected:
    AxMenuItem* m_menuItem;
};

/**
    @class AxEventActivator

    Sends an event to a given event sink.

    @category{ax}

 */

class AxEventActivator: public AxActivator
{
    DECLARE_DYNAMIC_CLASS( AxEventActivator )

public:
// Constructors

    AxEventActivator() { Init(); }
    AxEventActivator(const AxEventActivator& activator) { Init(); Copy(activator); }

    AxEventActivator(AxMenuItem* item, wxEvtHandler* sink, long eventId)
    { Init(); m_menuItem = item; m_sink = sink; m_eventId = eventId; }
    ~AxEventActivator() {}

// Operations

    void Init() { m_sink = NULL; m_eventId = -1; }

    void Copy(const AxEventActivator& activator);

    virtual AxActivator* Clone() const { return new AxEventActivator(*this); }

    virtual AxMenu* Activate(AxMenuController* controller, AxMenuItem* item);

    wxEvtHandler* GetEventSink() const { return m_sink; }
    void SetEventSink(wxEvtHandler* sink) { m_sink = sink; }

    long GetEventId() const { return m_eventId; }
    void SetEventId(long eventId) { m_eventId = eventId; }

protected:
    wxEvtHandler*   m_sink;
    long            m_eventId;
};

/**
    @class AxUpActivator

    Goes up a level.

    @category{ax}
 */

class AxUpActivator: public AxActivator
{
    DECLARE_DYNAMIC_CLASS( AxUpActivator )

public:
// Constructors

    AxUpActivator() { Init(); }
    AxUpActivator(const AxUpActivator& activator) { Init(); Copy(activator); }

    ~AxUpActivator() {}

// Operations

    void Init() { /* m_controller = NULL; */ }

    virtual AxActivator* Clone() const { return new AxUpActivator(*this); }

    void Copy(const AxUpActivator& activator);

    virtual AxMenu* Activate(AxMenuController* controller, AxMenuItem* item);

protected:
};

/**
    @class AxAutoUpdateActivator

    This class stores label and description specifications which
    are used to automatically update the label and/or description.
    Just override the CreateString function to substitute symbols into label
    and description.
    
    Use this when the menu item label and description might change over time.
 
    @category{ax}
 */

class AxAutoUpdateActivator: public AxActivator
{
public:
    
    DECLARE_CLASS( AxAutoUpdateActivator )

public:
// Constructors

    AxAutoUpdateActivator() { Init(); }

    AxAutoUpdateActivator(
        const wxString& labelSpec,
        const wxString& descriptionSpec);

    AxAutoUpdateActivator(const AxAutoUpdateActivator& activator) { Init(); Copy(activator); }

    void Init();

    void Copy(const AxAutoUpdateActivator& activator);

// New overrides

    /// Create the menu label or description, for example by substituting keywords
    /// in @a spec. The result will then be used by UpdateItem to set the label
    /// or description.
    virtual wxString CreateString(const wxString& spec, bool isLabel) = 0;

// Old overrides and implementation

    /// Called just before the menu item is displayed.
    virtual bool BeforeDisplay(AxMenuController* controller, AxMenuItem* item);

    /// Called during display, at intervals.
    virtual bool UpdateUI(AxMenuController* controller, AxMenuItem* item);

    /// Update label or description
    bool UpdateItem(AxMenuController* controller, AxMenuItem* item);

    /// Get the label specification
    const wxString& GetLabelSpec() const { return m_labelSpec; }

    /// Set the label specification
    void SetLabelSpec(const wxString& spec) { m_labelSpec = spec; }

    /// Get the description specification
    const wxString& GetDescriptionSpec() const { return m_descriptionSpec; }

    /// Set the description specification
    void SetDescriptionSpec(const wxString& spec) { m_descriptionSpec = spec; }

protected:
    wxString            m_labelSpec;
    wxString            m_descriptionSpec;
};

#endif
    // _AX_ACTIVATOR_H_
